package cn.car.biz.carAccess.support.impl;

import cn.car.biz.carAccess.support.abs.AbstractSupport;
import cn.car.domains.ctx.PlateDetectedContext;
import cn.car.domains.entity.*;
import cn.car.domains.enums.EmissionStandardEnum;
import cn.car.domains.enums.UploadGovStatusEnum;
import cn.car.domains.enums.VehicleTypeEnum;
import cn.car.exception.CarAccessControlException;
import cn.car.service.VehicleBlackInfoService;
import cn.car.service.VehicleCommonLedgerInfoService;
import cn.car.service.VehicleEntryExitInfoService;
import cn.car.service.VehicleEntryExitLedgerInfoService;
import cn.car.service.config.SystemConfig;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Slf4j
public class EnvLedgerSupport extends AbstractSupport {

    @Resource
    private VehicleBlackInfoService vehicleBlackInfoService;

    @Resource
    private VehicleEntryExitInfoService vehicleEntryExitInfoService;

    @Resource
    private SystemConfig systemConfig;

    @Resource
    private VehicleEntryExitLedgerInfoService vehicleEntryExitLedgerInfoService;

    @Resource
    private VehicleCommonLedgerInfoService vehicleCommonLedgerInfoService;


    @Override
    public String supportName() {
        return VehicleTypeEnum.ENTRY_EXIT.name();
    }

    @Override
    public void processIn(PlateDetectedContext context) {
        super.processIn(context);

        VehicleCommonInfoEntity vehicleCommonInfoEntity = context.getVehicleCommonInfoEntity();
        List<VehicleBlackInfoEntity> vehicleBlackInfoEntities = vehicleBlackInfoService.queryByVehicleNumber(vehicleCommonInfoEntity.getVehicleNumber());
        if (CollectionUtil.isNotEmpty(vehicleBlackInfoEntities)) {
            if ("0".equals(vehicleBlackInfoEntities.get(0).getStatus())) {
                String exceedReason = vehicleBlackInfoEntities.get(0).getExceedReason();
                log.info("[GATE_ACCESSOR ENV_LEDGER] processIn, notPass. 黑名单车辆, vehicleNumber in blackInfo, so the vehicle can not pass");
                throw CarAccessControlException.SYSTEM_ERROR.newInstance("黑名单车辆，禁止通行！管控原因：" + exceedReason);
            }
        }

        VehicleEntryExitInfoEntity vehicleEntryExitEntity = vehicleEntryExitInfoService.queryById(vehicleCommonInfoEntity.getAssociationId());
        if (vehicleEntryExitEntity == null) {
            log.error("[GATE_ACCESSOR ENV_LEDGER] processIn, notPass. 找不到运输车信息, could not find vehicle entry exit info by commonInfo:{}"
                    , JSONObject.toJSONString(vehicleCommonInfoEntity));
            throw CarAccessControlException.SYSTEM_ERROR.newInstance("找不到运输车信息");
        }

        context.setVehicleEntryExitInfoEntity(vehicleEntryExitEntity);

        EmissionStandardEnum emissionStandard = EmissionStandardEnum.govCodeOf(vehicleEntryExitEntity.getEmissionStandard());
        if (null == emissionStandard) {
            log.error("[GATE_ACCESSOR ENV_LEDGER] processIn, notPass. could not find emission standard by emissionStandard: {}, vehicleEntryExitEntity:{}"
                    , vehicleEntryExitEntity.getEmissionStandard(), JSON.toJSONString(vehicleEntryExitEntity));
            throw CarAccessControlException.SYSTEM_ERROR.newInstance("未找到排放标准");
        }
        EmissionStandardEnum govEmissionStandardMin = EmissionStandardEnum.valueOf(systemConfig.getGovEmissionStandardMin().get());

        if (emissionStandard.getIndex() < govEmissionStandardMin.getIndex()) {

            log.info("[GATE_ACCESSOR ENV_LEDGER] processIn, notPass. vehicle emission standard is lower than the minimum standard, 排放管控. emissionStandard: {}, govEmissionStandardMin: {}"
                    , emissionStandard.getDesc(), govEmissionStandardMin.getDesc());
            throw CarAccessControlException.SYSTEM_ERROR.newInstance("未达到最低排放标准");
        }

        // 4.如果配置了永远不打开，直接返回关门
        String controlFlag = systemConfig.getVehicleEntryExitControlIn().get();
        if (!"ON".equals(controlFlag)) {
            log.info("[GATE_ACCESSOR ENV_LEDGER] processIn, notPass. vehicleEntryExitControlIn is false, 人工管控.");
            throw CarAccessControlException.SYSTEM_ERROR.newInstance("当前人工管控");
        }

        log.info("[GATE_ACCESSOR ENV_LEDGER] processIn, canPass 通行. vehicleEntryExitEntity: {}", JSON.toJSONString(vehicleEntryExitEntity));
    }

    @Override
    public void processOut(PlateDetectedContext context) {

        super.processOut(context);
        VehicleCommonInfoEntity vehicleCommonInfoEntity = context.getVehicleCommonInfoEntity();

        VehicleEntryExitInfoEntity vehicleEntryExitEntity = vehicleEntryExitInfoService.queryById(vehicleCommonInfoEntity.getAssociationId());
        if (vehicleEntryExitEntity == null) {
            log.error("[GATE_ACCESSOR ENV_LEDGER] processIn, notPass. 找不到运输车信息, could not find vehicle entry exit info by commonInfo:{}"
                    , JSONObject.toJSONString(vehicleCommonInfoEntity));
            throw CarAccessControlException.SYSTEM_ERROR.newInstance("找不到运输车信息");
        }

        context.setVehicleEntryExitInfoEntity(vehicleEntryExitEntity);
        log.info("[GATE_ACCESSOR ENV_LEDGER] processIn, canPass 通行. vehicleEntryExitEntity: {}", JSON.toJSONString(context.getVehicleEntryExitInfoEntity()));

    }

    @Override
    public void recordIn(PlateDetectedContext context) {

        super.recordIn(context);

        VehicleEntryExitInfoEntity vehicleEntryExitInfoEntity = context.getVehicleEntryExitInfoEntity();

        VehicleCommonLedgerInfoEntity vehicleCommonLedgerInfoEntity = context.getVehicleCommonLedgerInfoEntity();
        //保存运输车台账
        VehicleEntryExitLedgerInfoEntity vehicleEntryExitLedgerInfoEntity = new VehicleEntryExitLedgerInfoEntity();


        vehicleEntryExitLedgerInfoEntity.setVehicleNumber(vehicleEntryExitInfoEntity.getVehicleNumber());
        vehicleEntryExitLedgerInfoEntity.setEntryExitVehicleType(vehicleEntryExitInfoEntity.getEntryExitVehicleType());

        vehicleEntryExitLedgerInfoEntity.setEntryPlateImgUrl(vehicleCommonLedgerInfoEntity.getEntryPlateImgUrl());
        vehicleEntryExitLedgerInfoEntity.setEntryVehicleImgUrl(vehicleCommonLedgerInfoEntity.getEntryVehicleImgUrl());
        vehicleEntryExitLedgerInfoEntity.setEntryCameraIp(vehicleCommonLedgerInfoEntity.getEntryCameraIp());
        vehicleEntryExitLedgerInfoEntity.setEntryTime(vehicleCommonLedgerInfoEntity.getEntryTime());
        vehicleEntryExitLedgerInfoEntity.setEntryUploadStatus(UploadGovStatusEnum.INIT.name());

        vehicleEntryExitLedgerInfoService.insert(vehicleEntryExitLedgerInfoEntity);

        Long id = vehicleEntryExitLedgerInfoEntity.getId();
        vehicleCommonLedgerInfoEntity.setAssociationId(id);

        vehicleCommonLedgerInfoService.updateAssociationId(vehicleCommonLedgerInfoEntity.getId(), id);

        context.setVehicleEntryExitLedgerInfoEntity(vehicleEntryExitLedgerInfoEntity);
    }

    @Override
    @Transactional
    public void recordOut(PlateDetectedContext context) {
        super.recordOut(context);

        //找上一条记录、
        VehicleEntryExitInfoEntity vehicleEntryExitInfoEntity = context.getVehicleEntryExitInfoEntity();
        VehicleCommonLedgerInfoEntity vehicleCommonLedgerInfoEntity = context.getVehicleCommonLedgerInfoEntity();
        VehicleEntryExitLedgerInfoEntity lastVehicleEntity = vehicleEntryExitLedgerInfoService.getLastLedgerByVehicleNumber(context.getVehicleCommonInfoEntity().getVehicleNumber());

        if (lastVehicleEntity == null || lastVehicleEntity.getExitTime() != null) {
            //新增一条记录
            VehicleEntryExitLedgerInfoEntity vehicleEntryExitLedgerInfoEntity = new VehicleEntryExitLedgerInfoEntity();

            vehicleEntryExitLedgerInfoEntity.setVehicleNumber(vehicleEntryExitInfoEntity.getVehicleNumber());
            vehicleEntryExitLedgerInfoEntity.setEntryExitVehicleType(vehicleEntryExitInfoEntity.getEntryExitVehicleType());

            vehicleEntryExitLedgerInfoEntity.setExitPlateImgUrl(vehicleCommonLedgerInfoEntity.getExitPlateImgUrl());
            vehicleEntryExitLedgerInfoEntity.setExitVehicleImgUrl(vehicleCommonLedgerInfoEntity.getExitVehicleImgUrl());
            vehicleEntryExitLedgerInfoEntity.setExitCameraIp(vehicleCommonLedgerInfoEntity.getExitCameraIp());
            vehicleEntryExitLedgerInfoEntity.setExitTime(vehicleCommonLedgerInfoEntity.getExitTime());
            vehicleEntryExitLedgerInfoEntity.setExitUploadStatus(UploadGovStatusEnum.INIT.name());

            vehicleEntryExitLedgerInfoService.insert(vehicleEntryExitLedgerInfoEntity);

            vehicleCommonLedgerInfoService.updateAssociationId(vehicleCommonLedgerInfoEntity.getId(), vehicleEntryExitLedgerInfoEntity.getId());

            vehicleCommonLedgerInfoEntity.setAssociationId(vehicleEntryExitLedgerInfoEntity.getId());

            context.setVehicleEntryExitLedgerInfoEntity(vehicleEntryExitLedgerInfoEntity);
        } else {
            //更新上一条记录出厂信息
            lastVehicleEntity.setExitPlateImgUrl(vehicleCommonLedgerInfoEntity.getExitPlateImgUrl());
            lastVehicleEntity.setExitVehicleImgUrl(vehicleCommonLedgerInfoEntity.getExitVehicleImgUrl());
            lastVehicleEntity.setExitCameraIp(vehicleCommonLedgerInfoEntity.getExitCameraIp());
            lastVehicleEntity.setExitTime(vehicleCommonLedgerInfoEntity.getExitTime());
            lastVehicleEntity.setExitUploadStatus(UploadGovStatusEnum.INIT.name());
            vehicleEntryExitLedgerInfoService.update(lastVehicleEntity);
            context.setVehicleEntryExitLedgerInfoEntity(lastVehicleEntity);
        }
    }

    @Override
    public void manualRecordIn(PlateDetectedContext context) {

        //能走到这一步，数据库里一定有东西
        context.setManualOperator("manual");
        this.recordIn(context);
    }

    @Override
    public void manualRecordOut(PlateDetectedContext context) {
        //能走到这一步，数据库里一定有东西
        context.setManualOperator("manual");
        this.recordOut(context);
    }
}
